import {
  InternalAxiosRequestConfig,
  AxiosResponse,
  AxiosInstance,
  AxiosError
} from "axios";

export type RequestOption<T = ResponseData> = {
  onRequest: (
    config: InternalAxiosRequestConfig
  ) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
  isSuccess: (response: AxiosResponse<T>) => boolean;
  onFail: (
    response: AxiosResponse<T>,
    instance: AxiosInstance
  ) => Promise<AxiosResponse<T> | null> | Promise<void>;
  onError: (error: AxiosError<T>) => any | Promise<any>;
  transformResponse: (response: AxiosResponse<T>) => T;
};

// 返回数据类型map
export type ResponseMap = {
  blob: Blob;
  text: string;
  arrayBuffer: ArrayBuffer;
  stream: ReadableStream<Uint8Array>;
  document: Document;
};

// 返回体数据类型
export type ResponseType = keyof ResponseMap | "json";

// 根据设置的responseType获取返回数据类型
export type MappedType<
  R extends ResponseType,
  JsonType = any
> = R extends keyof ResponseMap ? ResponseMap[R] : JsonType;

// json返回体：response.data
export type ResponseData<T = any> = {
  code: string;
  message: string;
  data: T;
};

export type FlatResponseSuccessData<
  T = any,
  R extends ResponseType = "json"
> = {
  data: T | MappedType<R, T>;
  error: null;
  response: AxiosResponse<ResponseData<T>>;
};

export type FlatResponseFailData<T = any> = {
  data: null;
  error: AxiosError<ResponseData<T>>;
  response: AxiosResponse<ResponseData<T>> | undefined;
};

export type FlatResponseData<T = any, R extends ResponseType = "json"> =
  | FlatResponseSuccessData<T, R>
  | FlatResponseFailData<T>;
